﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sharp.DataTransferObject.Workflow;
using Sharp.Domain.PlatformBoundedContext.WorkFlowModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.WorkFlowModule.Engine.Business.EntitySQLServer;
using Sharp.Domain.PlatformBoundedContext.WorkFlowModule.Engine.Business.Manager;
using Sharp.Domain.Repositories;
using Sharp.Infrastructure;
using Sharp.Infrastructure.Crosscutting;
using Sharp.Infrastructure.Search;

namespace Sharp.Application.Platform
{
    public partial class WorkflowServiceImpl : ApplicationService, Sharp.ServiceContracts.IWorkflowService
    {
        private IProcessEntityRepository _processEntityRepository;
        private ITaskEntityRepository _taskEntityRepository;
        private IProcessManager _processManager;

        private IActivityInstanceManager _activityInstanceManager;
        public WorkflowServiceImpl(IRepositoryContext context,
            IProcessEntityRepository processEntityRepository,
            ITaskEntityRepository taskEntityRepository,
            IProcessManager processManager,
            IActivityInstanceManager activityInstanceManager
        )
            : base(context)
        {
            _processEntityRepository = processEntityRepository;
            _taskEntityRepository = taskEntityRepository;
            _processManager = processManager;
            _activityInstanceManager = activityInstanceManager;
        }

        #region 保存流程
        /// <inheritdoc />
        /// <summary>
        /// 保存流程
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [Logging("保存流程“{@p0.ProcessName}”")]
        public Result SaveProcess(ProcessDTO model)
        {
            Result res = new Result();
            var info = model.To<ProcessEntity>();
            if (info.Id.IsEmpty())
            {
                _processManager.CreateProcess(info);
            }
            else
            {
                _processEntityRepository.AutoUpdateFields(info).Update(info);
                _processEntityRepository.Context.Commit();
            }
            Context.Commit();
            return res;
        }
        #endregion

        /// <summary>
        /// 获取流程定义文件
        /// </summary>
        /// <param name="id">流程ID</param>
        /// <returns></returns>
        public ProcessDTO GetProcessInfo(int id)
        {
            return _processEntityRepository.Get(id).To<ProcessDTO>();
        }

        /// <summary>
        /// 创建流程定义记录
        /// </summary>
        /// <param name="entity">流程定义实体</param>
        /// <returns>新ID</returns>
        public int CreateProcess(ProcessDTO entity)
        {
            var processID = _processManager.CreateProcess(entity.To<ProcessEntity>());

            return processID;
        }
        ///// <summary>
        ///// 更新流程定义记录
        ///// </summary>
        ///// <param name="entity">流程</param>
        //public void UpdateProcess(ProcessDTO entity)
        //{
        //    _processManager.Update(entity.To<ProcessEntity>());
        //}

        /// <summary>
        /// 删除流程定义记录
        /// </summary>
        /// <param name="processGUID">流程GUID</param>
        /// <param name="version">版本</param>
        public void DeleteProcess(string processGUID, string version)
        {
            _processManager.Delete(processGUID, version);
        }
        /// <summary>
        /// 删除流程定义记录
        /// </summary>
        /// <param name="ids"></param>
        public Result DeleteProcessById(int[] ids)
        {
            Result res = new Result();
            if (ids == null || ids.Length == 0)
            {
                res.Err = "缺少Id。";
                return res;
            }
            _processEntityRepository.Remove(ids);
            _processEntityRepository.Context.Commit();

            return res;
        }

        /// <summary>
        /// 流程定义数据读取
        /// </summary>
        /// <param name="processGUID">流程定义GUID</param>
        /// <param name="version">版本号</param>
        /// <returns>流程</returns>
        public ProcessDTO GetProcessByVersion(string processGUID, string version = null)
        {
            var entity = _processManager.GetByVersion(processGUID, version);

            return entity.To<ProcessDTO>();
        }
        /// <summary>
        /// 获取流程定义数据（只包括基本属性）
        /// </summary>
        /// <returns></returns>
        public IList<ProcessDTO> GetProcessListSimple()
        {
            var list = _processManager.GetListSimple();
            return list.To<List<ProcessDTO>>();
        }

        /// <summary>
        /// 获取当前版本的流程定义记录
        /// </summary>
        /// <param name="processGUID">流程GUID</param>
        /// <returns>流程</returns>
        public ProcessDTO GetProcess(string processGUID)
        {
            return _processManager.GetByVersion(processGUID, null).To<ProcessDTO>();
        }

        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pf"></param>
        /// <returns></returns> 
        public PagedResult<ProcessDTO> GetProcessPaged(PagingFeature pf)
        {
            return _processEntityRepository.Pagging(pf).To<ProcessEntity, ProcessDTO>(); ;
        }

        /// <summary>
        /// 保存流程定义的xml文件
        /// </summary>
        /// <param name="entity">流程文件实体</param>
        public void SaveProcessFile(ProcessFileDTO entity)
        {
            _processManager.SaveProcessFile(entity.To<ProcessFileEntity>());
        }

        /// <summary>
        ///  获取正在运行中的活动实例
        ///  </summary>
        ///  <param name="appInstanceID">应用实例ID</param>
        ///  <param name="processGUID">流程GUID</param>
        /// <returns>活动实例列表</returns>
        public IList<ActivityInstanceDTO> GetRunningActivityInstance(string appInstanceID, string processGUID)
        {
            var list = _activityInstanceManager.GetRunningActivityInstanceList(appInstanceID, processGUID).ToList();
            return list.To<List<ActivityInstanceDTO>>();
        }

        /// <summary>
        /// 流程定义的XML文件获取
        /// </summary>
        /// <param name="processGUID">流程GUID</param>
        /// <param name="version">版本</param>
        /// <returns>流程文件</returns>
        public ProcessFileDTO GetProcessFile(string processGUID, string version)
        {
            return _processManager.GetProcessFile(processGUID, version).To<ProcessFileDTO>();

        }
        /// <summary>
        /// 获取流程定义文件
        /// </summary>
        /// <param name="id">流程ID</param>
        /// <returns></returns>
        public ProcessFileDTO GetProcessFileByID(int id)
        {
            return _processManager.GetProcessFileByID(id).To<ProcessFileDTO>();
        }
    }
}